package com.credithc.signature.facade.controller.fadada;


import com.alibaba.fastjson.JSONObject;
import com.credithc.baseserv.core.message.Message;
import com.credithc.signature.common.constant.FddConstant;
import com.credithc.signature.common.mapper.FddAuthCompanyMapper;
import com.credithc.signature.common.mapper.FddAuthPersonMapper;
import com.credithc.signature.common.mapper.SignCallbackMapper;
import com.credithc.signature.common.po.FddAuthCompany;
import com.credithc.signature.common.po.FddAuthPerson;
import com.credithc.signature.common.po.SignCallback;
import com.credithc.signature.common.ro.facade.QueryAuthenticationStatusReq;
import com.credithc.signature.common.to.CallBackCompany;
import com.credithc.signature.common.to.CallBackPerson;
import com.credithc.signature.common.utils.HttpClientProxy;
import com.credithc.signature.facade.client.FadadaRemoteClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

/**
 * 描述：法大大实名认证异步通知<br/>
 * 作者：hujingbo
 * 创建：2019/5/30 15:33
 * 版本：v1.0.0<br/>
 */
@RestController
@RequestMapping("/api/signaturefacade/v1")
@Slf4j
public class FddAsyncNotifyController {

    @Autowired
    FadadaRemoteClient remote;

    @Autowired
    FddAuthPersonMapper fddAuthPersonMapper;

    @Autowired
    FddAuthCompanyMapper fddAuthCompanyMapper;

    @Autowired
    SignCallbackMapper signCallbackMapper;


    /**
     * 实名认证异步通知
     *
     * @param appId      接入平台唯一标识
     * @param serialNo   实名序列号（交易号）
     * @param status     激活状态
     * @param customerId 客户编号
     * @param statusDesc 状态描述
     */
    @ResponseBody
    @PostMapping("/auth/notify")
    public void fddNotify(String appId, String serialNo, String status, String customerId, String statusDesc) {
        log.info("法大大【实名认证】异步通知返回参数：appId={},serialNo={},status={},customerId={},statusDesc={}", appId, serialNo, status, customerId, statusDesc);
        // 如果是成功状态，则调用查询接口补全数据字段信息，因为此回调接口返回信息太少
        String sealCode = "";
        if (FddConstant.PERSON_AUTH_SUCCESS.equals(status) || FddConstant.COMPANY_AUTH_SUCCESS.equals(status)) {
            try {
                sealCode = completeAuthInfo(serialNo, status, customerId, statusDesc);
            } catch (Exception e) {
                log.error("法大大【实名认证】异步通知,补全认证信息时发生异常", e);
            }
        }

        String callbackUrl = null;
        String notifyUrl = null;
        Boolean isReturn = false;
        // 更新数据库状态
        FddAuthPerson fddAuthPerson = new FddAuthPerson();
        fddAuthPerson.setTransactionId(serialNo);
        FddAuthPerson fddAuthPerson1 = fddAuthPersonMapper.selectOne(fddAuthPerson);
        if (fddAuthPerson1 != null) {
            callbackUrl = fddAuthPerson1.getNotifyUrl();
            notifyUrl = fddAuthPerson1.getNotifyUrl();
            isReturn = fddAuthPerson1.getReturnNotifyUrlParams();
        } else {
            FddAuthCompany fddAuthCompany = new FddAuthCompany();
            fddAuthCompany.setTransactionId(serialNo);
            FddAuthCompany fddAuthCompany1 = fddAuthCompanyMapper.selectOne(fddAuthCompany);
            callbackUrl = fddAuthCompany1.getNotifyUrl();
            notifyUrl = fddAuthCompany1.getNotifyUrl();
            isReturn = fddAuthCompany1.getReturnNotifyUrlParams();
        }
        try {
            // 通知业务系统
            JSONObject object = buildRspMsg(status, statusDesc, notifyUrl, isReturn, serialNo, customerId,sealCode);
            log.info("法大大【实名认证】异步通知业务系统参数:{}", object.toJSONString());
            HttpClientProxy.post(callbackUrl, object);
            log.info("法大大【实名认证】异步通知业务系统成功......");
        } catch (Exception e) {
            log.error("法大大【实名认证】异步通知业务系统失败......", e);
        }
    }

    @ResponseBody
    @PostMapping("/sign/notify")
    public void fddSignNotify(String contract_id, String transaction_id, String result_code, String result_desc, String timestamp,String msg_digest) {
        log.info("法大大【手动签章】异步通知返回参数：contract_id={},transaction_id={},result_code={},result_desc={},timestamp={},msg_digest={}", contract_id, transaction_id, result_code, result_desc,timestamp ,msg_digest);
        //todo
        Example example = new Example(SignCallback.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("transactionId",transaction_id);
        criteria.andEqualTo("contractId",contract_id);
        SignCallback signCallback = new SignCallback();
        signCallback.setResultDesc(result_desc);
        if ("3000".equals(result_code)){
            signCallback.setStatus(1);
        }else{
            signCallback.setStatus(2);
        }
        signCallbackMapper.updateByExampleSelective(signCallback,example);
        SignCallback signCallback1 = signCallbackMapper.selectOneByExample(example);

        try {
            // 通知业务系统
            JSONObject object = buildSignRspMsg(contract_id,signCallback1.getSealCode(),signCallback1.getCustomerId(),signCallback1.getStatus(),msg_digest,signCallback1.getCallbackUrl());
            log.info("法大大【手动签章】异步通知业务系统参数:{}", object.toJSONString());
            HttpClientProxy.post(signCallback1.getCallbackUrl(), object);
            log.info("法大大【手动签章】异步通知业务系统成功......");
        } catch (Exception e) {
            log.error("法大大【手动签章】异步通知业务系统失败......", e);
        }
    }


    /**
         * 补全实名认证信息
         *
         * @param serialNo
         * @param status
         * @param customerId
         * @param statusDesc
         */
    private String completeAuthInfo(String serialNo, String status, String customerId, String statusDesc) {
        Message message = getMessage(serialNo, 1);
        int code = message.getCode();
        if (code == 1) {
            // 补全个人信息
            CallBackPerson callBackPerson = JSONObject.parseObject(JSONObject.toJSONString(message), CallBackPerson.class);
            callBackPerson.getData().setCustomerId(customerId);
            remote.completePersonInfo(callBackPerson, status, statusDesc);
        } else {
            Message message2 = getMessage(serialNo, 2);
            int code2 = message2.getCode();
            if (code2 == 1) {
                // 补全企业信息
                CallBackCompany callBackCompany = JSONObject.parseObject(JSONObject.toJSONString(message2), CallBackCompany.class);
                callBackCompany.getData().setCustomerId(customerId);
                remote.completeCompanyInfo(callBackCompany, status, statusDesc);
                // 插入公章信息
                return remote.completeSealInfo(callBackCompany);
            } else {
                log.error("未查询到该实名认证信息......serialNo={},customerId={}", serialNo, customerId);
            }
        }
        return null;
    }

    /**
     * 查询实名认证信息
     *
     * @param serialNo
     * @param accountType
     * @return
     */
    private Message getMessage(String serialNo, int accountType) {
        QueryAuthenticationStatusReq req = new QueryAuthenticationStatusReq();
        req.setTransactionNo(serialNo);
        req.setAccountType(accountType);
        if (FddConstant.ACCOUNT_PSERSON.equals(accountType)) {
            FddAuthPerson person = new FddAuthPerson();
            person.setTransactionId(serialNo);
            FddAuthPerson fddAuthPerson = fddAuthPersonMapper.selectOne(person);
            if (fddAuthPerson != null) {
                req.setChannelNo(fddAuthPerson.getChannelNo());
            }
        } else {
            FddAuthCompany company = new FddAuthCompany();
            company.setTransactionId(serialNo);
            FddAuthCompany fddAuthCompany = fddAuthCompanyMapper.selectOne(company);
            if (fddAuthCompany != null) {
                req.setChannelNo(fddAuthCompany.getChannelNo());
            }
        }
        Message message = null;
        try {
            message = remote.queryStatus(req);
        } catch (Exception e) {
            message = new Message();
            message.setCode(100);
        }
        return message;
    }

    /**
     * 封装返回消息
     *
     * @param status
     * @param statusDesc
     * @param notifyUrl
     * @param isReturn
     * @param serialNo
     * @param customerId
     * @return
     */
    private JSONObject buildRspMsg(String status, String statusDesc, String notifyUrl, Boolean isReturn, String serialNo, String customerId,String sealCode) {
        JSONObject object = new JSONObject();
        if (FddConstant.PERSON_AUTH_SUCCESS.equals(status) || FddConstant.COMPANY_AUTH_SUCCESS.equals(status)) {
            object.put("code", 1);
            object.put("msg", "success");
        } else {
            object.put("code", 100);
            object.put("msg", "fail");
        }
        // 封装data参数
        JSONObject object1 = new JSONObject();
        object1.put("status", status);
        object1.put("statusDesc", statusDesc);
        object1.put("transactionId", serialNo);
        object1.put("customerId", customerId);
        object1.put("sealCode",sealCode);
        // 封装serviceName字段
        if (isReturn) {
            if (notifyUrl.contains("serviceName")) {
                String params = notifyUrl.split("\\?")[1];
                String[] params2 = params.split("\\&");
                for (String ss : params2) {
                    String[] params3 = ss.split("\\=");
                    if ("serviceName".equals(params3[0])) {
                        object.put("serviceName", params3[1]);
                    } else {
                        object1.put(params3[0], params3[1]);
                    }
                }
            } else {
                String params = notifyUrl.split("\\?")[1];
                String[] params2 = params.split("\\&");
                for (String ss : params2) {
                    String[] params3 = ss.split("\\=");
                    object1.put(params3[0], params3[1]);
                }
            }
        }
        object.put("data", object1);
        return object;
    }

    private JSONObject buildSignRspMsg(String contract_id, String sealCode, String customerId, Integer status, String msg_digest,String notifyUrl) {
        JSONObject object = new JSONObject();
        if ( status ==1) {
            object.put("code", 1);
            object.put("msg", "success");
        } else {
            object.put("code", 100);
            object.put("msg", "fail");
        }
        JSONObject object1 = new JSONObject();
        object1.put("customerId", customerId);
        object1.put("status", status);
        object1.put("sealCode", sealCode);
        object1.put("msgDigest", msg_digest);
        object1.put("contractId", contract_id);

        try {
            if (notifyUrl.contains("serviceName")) {
                String params = notifyUrl.split("\\?")[1];
                String[] params2 = params.split("\\&");
                for (String ss : params2) {
                    String[] params3 = ss.split("\\=");
                    if ("serviceName".equals(params3[0])) {
                        object.put("serviceName", params3[1]);
                    } else {
                        object1.put(params3[0], params3[1]);
                    }
                }
            } else {
                String params = notifyUrl.split("\\?")[1];
                String[] params2 = params.split("\\&");
                for (String ss : params2) {
                    String[] params3 = ss.split("\\=");
                    object1.put(params3[0], params3[1]);
                }
            }
        } catch (Exception e) {
        }
        object.put("data", object1);
        return object;
    }

}
